Repository navigation
Conversation
…ive on navigate events.
…fill. The basic Navigation API polyfill now also fires a `navigatesuccess` event after `pushState` and `replaceState`, in addition to `navigate`. Note: Unlike the native implementation, the polyfill fires `navigate` after the URL has changed. Listening to `navigatesuccess` gives consistent timing for native and polyfilled implementations. Ref: ADR 0003 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
pat-inject is a non-class based pattern - the registry calls `init` on the same plain object for every element. Storing the UUID on `this` meant every element initialization overwrote it. Create the UUID locally where it is needed instead: for the delayed autoload trigger and the autoload-navigate listener id. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…lling it. The autoload-navigate trigger called `onTrigger` immediately during initialization and passed its return value (undefined) as the event listener. Pass a callback instead. The navigate event is deliberately not passed to `onTrigger`, which would call `preventDefault` on it and cancel the navigation. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…L changes only.
Listen to `navigatesuccess` instead of `navigate`. `navigate` is fired
before the navigation is committed - the URL is not yet updated and the
navigation might still be cancelled or unload the page.
Only re-trigger when the URL without the hash has changed. This ignores
anchor jumps and the same-URL `replaceState` calls which pat-inject uses to
mark history entries ("pageload", "anchor").
Do not initialize if the Navigation API is not available.
Ref: ADR 0003
Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…y: record. Recording history pushes a new history entry, which fires a navigation event which would re-trigger the injection again - an infinite loop. Log an error and do not initialize the trigger in that case. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…elements. When the element was removed from the DOM - e.g. replaced by an injection - remove the navigation event listener instead of triggering an injection on a detached element. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…ning injections. Rapid successive navigations are debounced using the `delay` option (default: 0). pat-inject drops triggers while an injection is in progress. For autoload-navigate this would leave the content in the state of an outdated URL. Instead, remember a pending trigger and run it once after the running injection has finished. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Reloading content on navigation or other events will be implemented in a dedicated pattern `pat-reload`, which uses pat-inject for the injection. Doing it in pat-inject would have required changing pat-inject's general contract - resolving the `url` relative to the current location and allowing other elements than `<a>` and `<form>` - for one use case, while the "when and which URL to reload" logic is not about injection. The polyfill's `navigatesuccess` event is kept. Ref: ADR 0001 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
pat-reload reloads the content of an element when an event is fired - by default `navigatesuccess`, after same-document navigations which changed the URL. This is useful for toolbars, breadcrumbs or sidebars which depend on the current location. pat-reload defines when and from which URL to reload. The injection itself is delegated to pat-inject and can be configured via `data-pat-inject` on the same element. By default, the content is injected into the element itself. Options: - `url`: Required. Relative URLs are appended to the current URL (without query string and hash), absolute URLs are used as-is. - `trigger-event`: Default `navigatesuccess`. Navigation API events are listened to on `window.navigation`, all others on `document`. - `delay`: Debounce time for successive events. Hash changes and same-URL replaceState calls do not trigger a reload. Events during a running reload trigger one more reload afterwards. Listeners are removed when the element was removed from the DOM. The base URL for relative URLs is the current location for now. A configurable base URL - e.g. for Plone default pages - will follow. Ref: ADR 0001 Ref: ADR 0002 Ref: ADR 0003 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Ref: ADR 0001 Ref: ADR 0002 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Ref: ADR 0001 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…e and pat-inject-finished event. - `execute` now returns `true` if the injection was started and `false` otherwise - for invalid configurations, denied confirmations or when an injection is already in progress. Previously it returned `undefined`. - A native `pat-inject-finished` event is dispatched on the pat-inject element after the injection has finished - successfully or not. Until now the injection state was only available via jQuery: the `pat-inject-triggered` jQuery data and the `pat-ajax-success` and `pat-ajax-error` events, which are triggered via jQuery and cannot be listened to with native event listeners. Ref: ADR 0004 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Only missing `#id` targets can be created. For other missing targets, `createTarget` returned `null` but `ensureTarget` still reported success. `execute` then failed with a TypeError when adding the loading class to the non-existing target. Now the configuration is reported as invalid and the injection is not started. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…tate. Track running reloads with the return value of pat-inject's `execute` and the native `pat-inject-finished` event, registered via `events.add_event_listener`, instead of reading the `pat-inject-triggered` jQuery data and listening to the jQuery-triggered `pat-ajax-success` and `pat-ajax-error` events. `pat-inject-finished` events bubbling up from injections within the element are ignored. jQuery is only used for calling pat-inject's API, which expects jQuery objects. Ref: ADR 0004 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…en the injection has finished.
This allows to use async/await with pat-inject:
try {
const injected = await inject.execute(cfgs, $el);
} catch (error) {
log.warn("Could not load.", error);
}
The Promise:
- resolves to `true` if the content was injected,
- resolves to `false` if the injection was not started - invalid
configuration, denied confirmation or an injection already in progress -
or if there was nothing to inject,
- rejects with an Error if the request failed with a network error or an
HTTP error status. The error's `cause` is the jqXHR object. pat-inject's
own error handling is done before.
The `pat-inject-finished` event is dispatched right before the Promise
settles. The Promise also waits for injections with a `process-delay`.
This replaces the boolean return value from the previous commit.
Note: Code which calls `execute` without handling the rejection now gets
unhandled Promise rejections for failed requests. The internal callers in
pat-inject, pat-collapsible and pat-expandable-tree catch them, as the error
is already handled by pat-inject.
Ref: ADR 0004
Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
Await the Promise returned by `inject.execute` instead of listening to the `pat-inject-finished` event. This removes the event listener and the filtering of events bubbling up from injections within the element. Failed reloads are logged as warnings and do not block further reloads. Ref: ADR 0004 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
pat-ajax only handles the result of the latest request, e.g. when a search form is submitted multiple times in a row. The requests were counted per URL globally though. When two different elements requested the same URL at the same time, the first element never received a `pat-ajax-success` event. For pat-inject this meant, that the first element stayed in the "injection in progress" state forever and could not inject again, and the Promise returned by `inject.execute` never settled. Now the requests are counted per element. The latest request of an element still wins - also when the same element requests different URLs, so that an outdated response cannot overwrite a newer one. Ref: ADR 0005 Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
…s Promise API and pat-ajax request tracking. - ADR 0001: Reload content on events with pat-reload instead of a pat-inject trigger. - ADR 0002: pat-reload URL resolution relative to the current location. - ADR 0003: React to navigations on navigatesuccess, not navigate. - ADR 0004: pat-inject's execute returns a Promise. - ADR 0005: pat-ajax handles the latest request per element. Assisted-by: Claude Opus 5.5 <noreply@anthropic.com>
thet
marked this pull request as draft
November 9, 2026 17:24
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft to create a Pattern to reload dom structures on event triggers.
E.g. reload toolbar on
navigatesuccessevent.This is a draft including documentation of the architecture/development process (ADR) and some fixes to pat-inject.
Needs to be taken up again.
Current status: Architecturing the Mockup
pat-base-urlPattern.